#include "widget.h"
#include "ui_widget.h"

QString ftpPath = "/laboratory/graduate/image/send.jpg";
QString receivePath = "/home/wr/laboratory/graduate/build-tcpPictureServer-unknown-Debug/receive.jpg";
QString  ftpIp = "192.168.0.105";
quint16  ftpPort = 21;
QString  ftpName = "wr";
QString  ftpPasswd = "123";


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    rect = QRect(0,0,ShowWindowSizeWidht,ShowWindowSizeHeight);
    view = new QGraphicsView(this);
    scene= new QGraphicsScene(view);
    view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//关闭上下滚动条
    view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//关闭左右滚动条
    view->setGeometry(rect);
    scene->setSceneRect(rect);
    scene->addItem(&item);
    view->setScene(scene);

    //    QImage image("/home/wr/Pictures/hbut.jpg");
    //    image = image.scaled(ShowWindowSizeWidht, ShowWindowSizeHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//缩放
    //    item.setPixmap(QPixmap::fromImage(image));

    resize(850,600);
    ui->contain->move(this->size().width()-ui->contain->size().width(),0);
    /* 1.获取主机ip
     * 2.建立连接，还要开始监听
     * 3.一旦有连接之后，会发出newConnect信号，立马获取currentClient
     */

    /* 1.获取主机ip */
    getHostInfo();
    /* 创建QTcpWidget */
    server = new QTcpServer(this);

    /* 2.建立连接，还要开始监听 */
    server->listen(QHostAddress::Any,serverPort);//开始侦听
    connect(server,SIGNAL(newConnection()),this,SLOT(newConnectSlot()));//有新的client连接会触发newConnetSlot槽
}

/* 1.获取主机ip */
void Widget::getHostInfo()
{
    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    for(int i = 0; i < ipAddressesList.size(); ++i)
    {
        if (ipAddressesList.at(i) != QHostAddress::LocalHost &&  ipAddressesList.at(i).toIPv4Address())
        {
            serverIP = ipAddressesList.at(i).toString();
        }
    }
    if(serverIP.isEmpty())
    {
        QMessageBox::about(this,"网卡无效","没有ip地址");
        serverIP = QHostAddress(QHostAddress::LocalHost).toString();
    }
    ui->serverip_ui->setText(serverIP);
}

/* 一旦有新的client来连接Widget之后
 * QTcpWidget内部的incomingConnection()函数
 * 会创建一个与客户端连接的QTcpSocket对象然后会
 * 发newConnect信号 */
void Widget::newConnectSlot()
{
    qDebug() << "new client connect";
    currentClient = server->nextPendingConnection();//获取临时连接的客户端socket
    QHostAddress clientip = this->currentClient->peerAddress();
    QString ip = clientip.toString();
    qDebug() << "client ip = " << ip;

    connect(currentClient,SIGNAL(readyRead()),this,SLOT(readyReadSlot()));
    connect(currentClient,SIGNAL(disconnected()),this,SLOT(clientDisconnectSlot()));
    ui->clinetNum_ui->setText(QString::number(++clinetNum));
}

/* 缓冲区中有数据，会发生readyRead信号,此槽函数读出缓冲区中数据 */
void Widget::readyReadSlot()
{
    file_tmp.setFileName(receivePath);
    if( !file_tmp.open(QIODevice::WriteOnly) )
    {
        qDebug() << "Error: cannot write file"<< (file_tmp.fileName()) << ":"<< (file_tmp.errorString());
    }
    array=((QByteArray)currentClient->readAll());

    if (!array.isNull()) {
        //qDebug() <<"server receive data ="<<array<<";data size="<<array.size();
    }else{
        qDebug() << "receive error!";
    }
    if(array == "start"){
        ftp.connectToHost(ftpIp,ftpPort);
        ftp.login(ftpName, ftpPasswd);
        connect(&ftp, SIGNAL(done(bool)), this, SLOT(ftpDownloadFinished(bool)));
    }else{
        downloadFile();
    }
}

void Widget::ftpDownloadFinished(bool error)
{
    file_tmp.flush();
    file_tmp.close();

    frame = cv::imread(receivePath.toStdString());
//    cv::imshow("aa",frame);
//    if(frame.data)
    {
        rec_image = Mat2QImage(frame);//Mat转QImage
        rec_image = rec_image.scaled(ShowWindowSizeWidht, ShowWindowSizeHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//缩放
        item.setPixmap(QPixmap::fromImage(rec_image));
        downLoadFinshed();
    }
}

bool flag=true;
void Widget::downloadFile()    //下载文件
{
    //qDebug()<<"ftp.get downloadFile";
    ftp.get(ftpPath, &file_tmp);
}
void Widget::clientDisconnectSlot()
{
    this->currentClient->close();
    ftp.close();
    file_tmp.close();
}

/* 当服务器接受完成，发送完成信号给客户端，让客户端再发送图片 */
void Widget::downLoadFinshed()
{
    currentClient->write("OK");
    if(!currentClient->waitForBytesWritten(3000)){
        currentClient->flush();
    }
}

/* 窗口关闭事件 */
void Widget::closeEvent(QCloseEvent *event)
{
    if(this->server->isListening())
        this->server->close();
    if(this->currentClient->isOpen())
    {
        this->currentClient->abort();
    }
}

Widget::~Widget()
{
    delete ui;
}
/* #########################  以下是稳定代码 ######################################### */
/*************************** 下面是QImge 和 Mat转换代码  *******************************/
/* Mat转 QImage*/
QImage Widget::Mat2QImage(const cv::Mat& mat)
{
    if(mat.type() == CV_8UC1)
    {
        //cout << "CV_8UC1 "<<endl;
        QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
        image.setColorCount(256);
        for(int i = 0; i < 256; i++)
        {
            image.setColor(i, qRgb(i, i, i));
        }
        uchar *pSrc = mat.data;
        for(int row = 0; row < mat.rows; row ++)
        {
            uchar *pDest = image.scanLine(row);
            memcpy(pDest, pSrc, mat.cols);
            pSrc += mat.step;
        }
        return image;
    }
    else if(mat.type() == CV_8UC3)
    {
        //cout << "CV_8UC3 "<<endl;
        const uchar *pSrc = (const uchar*)mat.data;
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
        return image.rgbSwapped();
    }
    else if(mat.type() == CV_8UC4)
    {
        //cout << "CV_8UC4 "<<endl;
        const uchar *pSrc = (const uchar*)mat.data;
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
        return image.copy();
    }
    else
    {
        //cout << "CV_8UC5 "<<endl;
        return QImage();
    }
}

/* QImage转Mat */
Mat Widget::QImage2Mat(QImage image)
{
    cv::Mat mat;

    if(QImage::Format_ARGB32 == image.format() || QImage::Format_RGB32 == image.format() || QImage::Format_ARGB32_Premultiplied == image.format())
    {
        mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
    }
    else if(QImage::Format_RGB888 == image.format())
    {
        mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
        cv::cvtColor(mat, mat, COLOR_BGR2RGB);
    }
    else if(QImage::Format_Indexed8 == image.format())
    {
        mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
    }
    return mat;
}


